/**
* AutoSWF - Cody Cushing. March 26, 2009
* Copyright (c) 2009 Cody Cushing
* No use restrictions. Maintain this notice in all versions. 
**/

package com.autoswf.core
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;

	/**
	 * Class for automating an InteractiveObject. Not required, just convenient.
	 */
	public class SpriteLink extends Sprite implements ILink
	{
		protected var _link:Link;
		protected var _events:Dictionary;
		
		
		/**
		 * Constructor.
		 */
		public function SpriteLink(id:String)
		{
			super();
			
			_link = new Link(id);
			_link.client = this;
			
			_events = new Dictionary(true);
		}
		
		public function get id():String
		{
			return _link.id;
		}
		
		public function addChildLink(link:ILink):void
		{
			_link.addChildLink(link);
		}
		
		public function removeChildLink(link:ILink):void
		{
			_link.removeChildLink(link);
		}
		
		public function addParentLink(link:ILink):void
		{
			_link.addParentLink(link);
		}
		
		public function removeParentLink(link:ILink):void
		{
			_link.removeParentLink(link);
		}
		
		public function sendUp(object:*):void
		{
			_link.sendUp(object);
		}
		
		
		/**
		 * Checks if transport object is an event and if this class has that event listener,  
		 * invokes the handler, passing the event. Otherwise, the object is passed down the chain.
		 */
		public function sendDown(object:*):Object
		{
			var transport:Transport = Transport(object);
			if(transport.proposition is Event)
			{
				var event:Event = transport.proposition;
				if(_events.hasOwnProperty(event.type))
				{
					for each(var listener:Function in _events[event.type])
					{
						listener(event);
					}
				}
				return null
			}
			return _link.sendDown(object);
		}
		
		
		/**
		 * Generates a function to proxy event handling for tracking/automation before 
		 * forwarding the event to handler function.
		 */
		public function addTrackingEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
		{
			if(!_events.hasOwnProperty(type))
			{
				_events[type] = new Dictionary(false);
			}
			
 			_events[type][listener] = function(event:Event):void
			{
				_link.sendUp(event);   /* Bubble events up */
				listener(event);       /* Invoke handler */
			}
			
			this.addEventListener(type, _events[type][listener], useCapture, priority, useWeakReference);
		}
		
		
		public function hasTrackingEventListener(type:String, listener:Function = null):Boolean
		{
			return (listener != null && _events[type] != null) ? _events[type].hasOwnProperty(listener) : _events.hasOwnProperty(type);
		}
		
		
		/**
		 * Removes proxy function as handler for event type, deletes proxy function.
		 */
		public function removeTrackingEventListener(type:String, listener:Function, useCapture:Boolean = false):void
		{
			if(_events[type] && _events[type][listener])
			{
				this.removeEventListener(type, _events[type][listener], useCapture);
				delete _events[type][listener];
				
				/* short cut to remove valueless key from dictionary */
				for each(var func:Function in _events[type]){ }
				
				if(func == null)
				{
					delete _events[type];
				}
			}
		}
		
	}
}